import { DownOutlined } from "@ant-design/icons"
import { district, shipping } from "@mall/api-services"
import { Button, Checkbox, Col, Form, Input, Modal, Popover, Radio, Row, Space, Table, Typography } from "antd"
import { ColumnProps } from "antd/es/table"
import * as _ from "lodash"
import * as React from "react"
import { useEffect, useState } from "react"

import classes from "./shipping-rate-form.module.scss"

const { Text } = Typography

interface CityCheckboxProps {
  province: district.Province
  city: district.City
  locations: string[]
  onChange: (locations: string[]) => void
}

function CityCheckbox(props: CityCheckboxProps) {
  const { province, city, locations, onChange } = props
  const countryIds = _.map(city.counties, country => country.id)
  const checkedLocations = _.intersection(locations, countryIds)
  const uncheckedLocations = _.difference(countryIds, checkedLocations)
  const content = <>
    <Space direction="vertical" style={{ maxHeight: "320px", overflow: "auto" }}>
      {_.map(city.counties, country =>
        <Checkbox key={country.id}
                  checked={_.includes(locations, province.id) ||
                  _.includes(locations, city.id) ||
                  _.includes(locations, country.id)}
                  children={country.name}
                  onChange={e => {
                    if (e.target.checked) {
                      const checkedCountryIds = _.intersection(countryIds, _.union(checkedLocations, [country.id]))
                      const uncheckedCountryIds = _.difference(countryIds, checkedCountryIds)
                      if (_.isEmpty(uncheckedCountryIds)) {
                        onChange(_.union(_.difference(locations, checkedCountryIds), [city.id]))
                      } else {
                        onChange(_.union(locations, [country.id]))
                      }
                    } else {
                      if (_.includes(locations, province.id) || _.includes(locations, city.id)) {
                        onChange(_.union(_.difference(locations, [city.id]), _.difference(countryIds, [country.id])))
                      } else {
                        onChange(_.difference(locations, [country.id]))
                      }
                    }
                  }}/>)}
    </Space>
  </>
  return <Checkbox key={city.id}
                   checked={_.includes(locations, province.id) || _.includes(locations, city.id)}
                   indeterminate={!(_.includes(locations, province.id) || _.includes(locations, city.id)) &&
                   !_.isEmpty(uncheckedLocations) && !_.isEmpty(checkedLocations)}
                   onChange={e => {
                     if (e.target.checked) {
                       onChange(_.union(_.difference(locations, countryIds), [city.id]))
                     } else {
                       onChange(_.difference(_.difference(locations, countryIds), [city.id]))
                     }
                   }}>
    <Popover content={content} trigger="click" placement="right">
      {city.name}
      <DownOutlined rotate={-90} style={{ fontSize: "12px" }}/>
    </Popover>
  </Checkbox>
}

interface ProvinceCheckboxProps {
  province: district.Province
  locations: string[]
  onChange: (locations: string[]) => void
}

function ProvinceCheckbox(props: ProvinceCheckboxProps) {
  const { province, locations, onChange } = props
  const cityIds = _.map(province.cities, city => city.id)
  const countryIds = _.chain(province.cities)
    .flatMap(city => [city, ..._.flatMap(province.cities, city => city.counties)])
    .map(country => country.id)
    .value()
  const checkedLocations = _.intersection(locations, countryIds)
  const uncheckedLocations = _.difference(countryIds, checkedLocations)

  const content = <>
    <Space direction="vertical" style={{ maxHeight: "320px", overflow: "auto" }}>
      {_.map(province.cities, city =>
        <CityCheckbox key={city.id}
                      province={province}
                      city={city}
                      locations={locations}
                      onChange={newLocations => {
                        if (_.includes(newLocations, city.id)) {
                          const uncheckedCityIds = _.difference(cityIds, newLocations)
                          if (_.isEmpty(uncheckedCityIds)) {
                            onChange(_.union(_.difference(newLocations, cityIds), [province.id]))
                          } else {
                            onChange(_.difference(_.difference(newLocations, [province.id]), uncheckedCityIds))
                          }
                        } else {
                          if (_.includes(newLocations, province.id)) {
                            onChange(_.union(_.difference(newLocations, [province.id]), _.difference(cityIds, [city.id])))
                          } else {
                            onChange(newLocations)
                          }
                        }
                      }}/>)}
    </Space>
  </>

  return <Checkbox key={province.id}
                   checked={_.includes(locations, province.id)}
                   indeterminate={!_.includes(locations, province.id) && !_.isEmpty(uncheckedLocations) && !_.isEmpty(checkedLocations)}
                   onChange={e => {
                     if (e.target.checked) {
                       onChange(_.union(_.difference(locations, countryIds), [province.id]))
                     } else {
                       onChange(_.difference(_.difference(locations, countryIds), [province.id]))
                     }
                   }}>
    <Popover content={content} trigger="click">
      {province.name}
      <DownOutlined style={{ fontSize: "12px" }}/>
    </Popover>
  </Checkbox>
}

interface ShippingRegionModalProps {
  visible?: boolean
  onCancel?: () => void
  // locations: string[]
}


function ShippingRegionModal(props: ShippingRegionModalProps) {
  const { visible, onCancel } = props
  const [regions, setRegions] = useState([] as district.Region[])

  const [newLocations, setNewLocations] = useState([] as string[])

  useEffect(() => {
    district.DistrictService.getRegions().countryId("1").scope(3).list()
      .then(setRegions)
  }, [])


  function handleCheckAll(checked: boolean) {
    if (checked) {
      setNewLocations(_.chain(regions).flatMap(region => region.provinces).map(province => province.id).value())
    } else {
      setNewLocations([])
    }
  }

  return (
    <Modal title="选择配送区域" width={700} className={classes.shippingRegionModal}
           visible={visible}
           onCancel={onCancel}
           footer={false}>
      {
        _.map(regions, region => {
          const provinceIds = _.map(region.provinces, province => province.id)
          const checkedProvinceIds = _.intersection(newLocations, provinceIds)
          const uncheckedProvinceIds = _.difference(provinceIds, checkedProvinceIds)

          const countryIds = _.chain(region.provinces)
            .flatMap(province => [province, ...province.cities, ..._.flatMap(province.cities, city => city.counties)])
            .map(country => country.id)
            .value()

          const checkedCountryIds = _.intersection(newLocations, countryIds)
          const uncheckedCountryIds = _.difference(provinceIds, checkedCountryIds)
          return (<div key={region.id} className={classes.regionBlock}>
            <Checkbox key={region.id} children={region.name}
                      checked={_.isEmpty(uncheckedProvinceIds) && !_.isEmpty(checkedProvinceIds)}
                      indeterminate={!_.isEmpty(uncheckedCountryIds) && !_.isEmpty(checkedCountryIds)}
                      onChange={e => {
                        if (e.target.checked) {
                          setNewLocations(_.union(_.difference(newLocations, countryIds), provinceIds))
                        } else {
                          setNewLocations(_.difference(_.difference(newLocations, countryIds), provinceIds))
                        }
                      }}/>
            {
              _.map(region.provinces, province =>
                <ProvinceCheckbox key={province.id}
                                  province={province}
                                  locations={checkedCountryIds}
                                  onChange={setNewLocations}/>)
            }
          </div>)
        })
      }
      <><Row justify="space-between" align="middle">
        <Col span={6}><Checkbox onChange={e => handleCheckAll(e.target.checked)}>全选</Checkbox></Col>
        <Col span={12} style={{ textAlign: "right" }}>
          <Space>
            {!_.isEmpty(newLocations) && <Text>已选择566个区域</Text>}
            <Button type="primary"
                    disabled={_.isEmpty(newLocations)}
                    onClick={() => console.log(newLocations)}>确定</Button>
          </Space>
        </Col>
      </Row></>
    </Modal>
  )
}

export default function ShippingRateForm() {
  const [shippingRegionModalVisible, setShippingRegionModalVisible] = useState(false)
  const layout = {
    labelCol: { span: 2 },
    wrapperCol: { span: 22 },
  }

  const tailLayout = {
    wrapperCol: { offset: 2, span: 16 },
  }
  const columns: ColumnProps<shipping.Zone>[] = [
    {
      title: "可配送区域",
      dataIndex: "locations",
      key: "locations",
    },
    {
      title: "首件(个)",
      dataIndex: "first",
      key: "first",
      width: "100px",
    },
    {
      title: "运费(元)",
      dataIndex: "firstCost",
      key: "firstCost",
      width: "100px",
    },
    {
      title: "续件(个)",
      dataIndex: "additional",
      key: "additional",
      width: "100px",
    },
    {
      title: "续费(元)",
      dataIndex: "additionalCost",
      key: "additionalCost",
      width: "100px",
    },
  ]

  function handleChangeShippingRegionModalVisible() {
    setShippingRegionModalVisible(!shippingRegionModalVisible)
  }


  return (
    <div className={classes.shippingRateForm}>
      <ShippingRegionModal visible={shippingRegionModalVisible} onCancel={handleChangeShippingRegionModalVisible}/>
      <Form
        {...layout} name="basic"
        initialValues={{ mode: shipping.RateMode.Package }}>
        <Form.Item label="运费名称" name="name"
                   rules={[{ required: true, message: "请输入运费名称!" }]}>
          <Input/>
        </Form.Item>
        <Form.Item label="计费方式" name="mode">
          <Radio.Group>
            <Radio value={shipping.RateMode.Package}>按件数</Radio>
            <Radio value={shipping.RateMode.Weight}>按重量</Radio>
          </Radio.Group>
        </Form.Item>
        <Form.Item label="配送区域">
          <Space direction="vertical" style={{ display: "flex" }}>
            <Table dataSource={[]} columns={columns}/>
            <Button type="primary"
                    onClick={handleChangeShippingRegionModalVisible}>指定可配送区域和运费</Button>
          </Space>
        </Form.Item>
        <Form.Item {...tailLayout}>
          <Space>
            <Button type="primary" htmlType="submit">保存</Button>
            <Button htmlType="submit">返回</Button>
          </Space>
        </Form.Item>
      </Form>
    </div>
  )

}
